package com.ruoyi.project.lely.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.framework.aspectj.lang.annotation.DataSource;
import com.ruoyi.framework.aspectj.lang.enums.DataSourceType;
import com.ruoyi.project.lely.bean.entity.LyAd;
import com.ruoyi.project.lely.bean.entity.LyArticle;
import com.ruoyi.project.lely.bean.entity.LyGoods;
import com.ruoyi.project.lely.bean.vo.LyGoodsNewsVO;
import com.ruoyi.project.lely.bean.vo.LyIndexVO;
import com.ruoyi.common.R;
import com.ruoyi.project.lely.constant.CommonConstant;
import com.ruoyi.project.lely.service.LyAdService;
import com.ruoyi.project.lely.service.LyArticleService;
import com.ruoyi.project.lely.service.LyGoodsService;
import com.ruoyi.project.lely.service.LyIndexService;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @Desc: 首页实现
 * @Author LuoYong
 * @Date 2022/1/14 10:45
 */
@Slf4j
@Service
@DataSource(value = DataSourceType.SLAVE)
public class indexServiceImpl implements LyIndexService {

    @Autowired
    private LyAdService adService;
    @Autowired
    private LyArticleService articleService;
    @Autowired
    private LyGoodsService goodsService;


    @Override
    public R getGoodsCount() {
        int count = goodsService.count(
                new LambdaQueryWrapper<LyGoods>()
                        .eq(LyGoods::getDeleted, CommonConstant.DEFAULT_ADDRESS_NO));
        return R.ok(count);
    }

    /**
     * 获取首页数据-同步
     *
     * @return
     */
    @Override
    public R getIndex() {
        LyIndexVO vo = new LyIndexVO();
        //轮播图banner
        List<LyAd> banners = adService.list();

        //消息提示快报
        List<LyArticle> articles = articleService.list(
                new LambdaQueryWrapper<LyArticle>()
                        .orderByDesc(LyArticle::getCreateTime));

        //今日推荐 & 新品
        List<LyGoods> goods = goodsService.list(
                new LambdaQueryWrapper<LyGoods>()
                        .and(n -> n.eq(LyGoods::getIsNew, CommonConstant.NEW_YES)
                                .or().eq(LyGoods::getIsHot, CommonConstant.HOT_YES))
                        .eq(LyGoods::getDeleted, CommonConstant.DEFAULT_ADDRESS_NO)
                        .orderByDesc(LyGoods::getCreateTime));

        vo.setBanner(banners);
        vo.setArticles(articles);
        if (CollUtil.isNotEmpty(goods)) {
            List<LyGoodsNewsVO> vos = new ArrayList<>();
            List<LyGoods> todayGoods =
                    goods.stream().filter(t -> CommonConstant.NEW_YES.equals(t.getIsNew())).collect(Collectors.toList());
            todayGoods.stream().forEach(n -> {
                LyGoodsNewsVO newsVO = new LyGoodsNewsVO();
                BeanUtils.copyProperties(n,newsVO);
                vos.add(newsVO);
            });
            vo.setTodayGoods(vos);

            List<LyGoodsNewsVO> vos1 = new ArrayList<>();
            List<LyGoods> news =
                    goods.stream().filter(t -> CommonConstant.HOT_YES.equals(t.getIsHot())).collect(Collectors.toList());
            news.stream().forEach(n -> {
                LyGoodsNewsVO newsVO = new LyGoodsNewsVO();
                BeanUtils.copyProperties(n,newsVO);
                vos1.add(newsVO);
            });
            vo.setNews(vos1);
        }
        // todo:缓存数据首页缓存数据.....

        return R.ok(vo);
    }

    /**
     * 获取首页数据-异步
     *
     * @return
     */
    @Override
    public R getIndexAsync() {
        LyIndexVO vo = new LyIndexVO();
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        try {
            //轮播图banner
            Callable<List<LyAd>> bannerListCallable = () -> adService.list();
            //消息提示快报
            Callable<List<LyArticle>> articleListCallable = () ->
                    articleService.list(
                            new LambdaQueryWrapper<LyArticle>()
                                    .orderByDesc(LyArticle::getCreateTime));
            //今日推荐 & 新品
            Callable<List<LyGoods>> goodsListCallable = () ->
                    goodsService.list(
                            new LambdaQueryWrapper<LyGoods>()
                                    .and(n -> n.eq(LyGoods::getIsNew, CommonConstant.NEW_YES)
                                            .or().eq(LyGoods::getIsHot, CommonConstant.HOT_YES))
                                    .eq(LyGoods::getDeleted, CommonConstant.DEFAULT_ADDRESS_NO)
                                    .orderByDesc(LyGoods::getCreateTime));

            FutureTask<List<LyAd>> bannerTask = new FutureTask<>(bannerListCallable);
            FutureTask<List<LyArticle>> articleTask = new FutureTask<>(articleListCallable);
            FutureTask<List<LyGoods>> goodsTask = new FutureTask<>(goodsListCallable);

            executorService.submit(bannerTask);
            executorService.submit(articleTask);
            executorService.submit(goodsTask);

            vo.setBanner(bannerTask.get());
            vo.setArticles(articleTask.get());
            List<LyGoods> goods = goodsTask.get();
            if (CollUtil.isNotEmpty(goods)) {
                List<LyGoodsNewsVO> vos = new ArrayList<>();
                List<LyGoods> todayGoods =
                        goods.stream().filter(t -> CommonConstant.NEW_YES.equals(t.getIsNew())).collect(Collectors.toList());
                todayGoods.stream().forEach(n -> {
                    LyGoodsNewsVO newsVO = new LyGoodsNewsVO();
                    BeanUtils.copyProperties(n,newsVO);
                    vos.add(newsVO);
                });
                vo.setTodayGoods(vos);

                List<LyGoodsNewsVO> vos1 = new ArrayList<>();
                List<LyGoods> news =
                        goods.stream().filter(t -> CommonConstant.HOT_YES.equals(t.getIsHot())).collect(Collectors.toList());
                news.stream().forEach(n -> {
                    LyGoodsNewsVO newsVO = new LyGoodsNewsVO();
                    BeanUtils.copyProperties(n,newsVO);
                    vos1.add(newsVO);
                });
                vo.setNews(vos1);
            }
            // 缓存数据首页缓存数据
            executorService.shutdown();

        } catch (Exception e) {
            log.error("首页信息获取失败：{}", e.getMessage());
            e.printStackTrace();
        }
        return R.ok(vo);
    }

}
